package plp.imperative2.command;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import plp.expressions1.util.Tipo;
import plp.expressions2.expression.ExpSoma;
import plp.expressions2.expression.ExpUnaria;
import plp.expressions2.expression.Expressao;
import plp.expressions2.expression.Id;
import plp.expressions2.expression.Valor;
import plp.expressions2.memory.AmbienteCompilacao;
import plp.expressions2.memory.AmbienteExecucao;
import plp.expressions2.memory.VariavelJaDeclaradaException;
import plp.expressions2.memory.VariavelNaoDeclaradaException;
import plp.imperative1.memory.AmbienteCompilacaoImperativa;
import plp.imperative1.memory.AmbienteExecucaoImperativa;
import plp.imperative1.memory.ListaValor;
import plp.imperative1.util.Lista;
import plp.imperative2.expression.TipoArray;

public class ListaExpressao extends Lista<Expressao> {

	public ListaExpressao() {

	}

	public ListaExpressao(Expressao expressao) {
		super(expressao, new ListaExpressao());
	}

	public ListaExpressao(Expressao expressao, ListaExpressao listaExpressao) {
		super(expressao, listaExpressao);
	}

	public ListaValor avaliar(AmbienteExecucaoImperativa ambiente)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
		if (length() >= 2)
			return new ListaValor(getHead().avaliar(ambiente),
					((ListaExpressao) getTail()).avaliar(ambiente));
		else if (length() == 1)
			return new ListaValor(getHead().avaliar(ambiente));
		else
			return new ListaValor();
	}

	public List<Tipo> getTipos(AmbienteCompilacaoImperativa ambiente)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {

		List<Tipo> result = new LinkedList<Tipo>();

		if (this.length() >= 2) {
			result.add(getHead().getTipo(ambiente));
			result.addAll(((ListaExpressao) getTail()).getTipos(ambiente));
		} else if (length() == 1) {
			result.add(getHead().getTipo(ambiente));
		}
		
		return result;
	}

	public Expressao[] getArray() {
		
		ArrayList<Expressao> lista = new ArrayList<Expressao>();
		if (getHead() != null) {
			lista.add(getHead());
		}
		Lista<Expressao> expressoes = getTail();
		if (expressoes != null) {
			while (expressoes.getHead() != null) {
				lista.add(expressoes.getHead());
				expressoes = expressoes.getTail();
			}
		}
		
		Expressao[] retorno = new Expressao[lista.size()];
		int index = 0;
		for (int i = lista.size() - 1; i >= 0; i--) {
			retorno[index++] = lista.get(i);
		}
		
		return retorno;
	}

	public static void main(String[] args) {
		Expressao exp1 = new ExpSoma(new Id("a"), new Id("b"));
		Expressao exp2 = new ExpSoma(new Id("d"), new Id("e"));
		Expressao exp3 = new ExpSoma(new Id("g"), new Id("f"));

		ListaExpressao lista = new ListaExpressao(exp1);/*(exp1, new ListaExpressao(
				exp2, new ListaExpressao(exp3)));*/
		Expressao[] array = lista.getArray();
		System.out.println(array.length);
	}

}
